package qc.module.ehs.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.IdentifierUtil;
import qc.module.ehs.dto.edurecord.EduRecordDto;
import qc.module.ehs.dto.edurecord.EduRecordQueryConditionDto;
import qc.module.ehs.dto.edurecord.EduRecordSetUsersDto;
import qc.module.ehs.dto.edurecord.EduRecordUsersDto;
import qc.module.ehs.entity.EhsEduRecord;
import qc.module.ehs.entity.EhsEduUser;
import qc.module.ehs.mapper.EhsEduRecordMapper;
import qc.module.ehs.repository.EhsEduRecordRepository;
import qc.module.ehs.repository.EhsEduUserRepository;
import qc.module.platform.dto.user.UserSimpleInfoDto;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 安全培训记录接口Service
 *
 * @author QuCheng Tech
 * @since 2024/10/29
 */
@Service
public class EhsEduRecordService {
    @Autowired
    private EhsEduRecordRepository repository;

    @Autowired
    private EhsEduUserRepository userRepository;

    /**
     * 查询记录
     *
     * @param condition 查询条件
     * @return List<EduRecordDto>
     * @author QuCheng Tech
     * @since 2024/10/29
     */
    public List<EduRecordDto> query(EduRecordQueryConditionDto condition) throws QCPromptException {
        if (condition == null)
            throw new QCPromptException("查询条件不能为空");
        if (StringUtils.isBlank(condition.getOrgcode()))
            throw new QCPromptException("组织代码不能为空");

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(condition.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }

        LambdaQueryWrapper<EhsEduRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsEduRecord::getOrgcode, condition.getOrgcode());
        //培训起始时间 >= 开始时间 and 培训结束时间 <= 结束时间
        if (beginDate != null && endDate != null) {
            Date begintm = beginDate;
            Date endtm = endDate;
            wrapper.and(q -> {
                q.ge(EhsEduRecord::getBegintm, begintm).le(EhsEduRecord::getEndtm, endtm);
            });
        }
        if (condition.getEdutype() != null) {
            wrapper.eq(EhsEduRecord::getEdutype, condition.getEdutype());
        }
        if (condition.getEdumode() != null) {
            wrapper.eq(EhsEduRecord::getEdumode, condition.getEdumode());
        }
        if (StringUtils.isNotBlank(condition.getKeywords())) {
            wrapper.and(q -> {
                q.like(EhsEduRecord::getTitle, condition.getKeywords()).or()
                        .like(EhsEduRecord::getContent, condition.getKeywords()).or()
                        .like(EhsEduRecord::getLocation, condition.getKeywords());
            });
        }

        List<EhsEduRecord> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            return EhsEduRecordMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 获取指定记录
     *
     * @param id 记录ID
     * @return EduRecordDto
     * @author QuCheng Tech
     * @since 2024/10/29
     */
    public EduRecordDto get(String id) {
        EhsEduRecord en = repository.selectById(id);
        if (Objects.nonNull(en)) {
            return EhsEduRecordMapper.MAPPER.toDto(en);
        }
        return null;
    }

    /**
     * 新增记录
     *
     * @param dto
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/10/29
     */
    public String add(EduRecordDto dto) {
        if (dto == null)
            return QCUnifyReturnValue.Warn("新增对象不能为空");
        if (StringUtils.isBlank(dto.getOrgcode()))
            return QCUnifyReturnValue.Warn("组织代码不能为空");
        if (StringUtils.isBlank(dto.getBegintm()))
            return QCUnifyReturnValue.Warn("开始时间不能为空");
        if (StringUtils.isBlank(dto.getEndtm()))
            return QCUnifyReturnValue.Warn("结束时间不能为空");
        if (StringUtils.isBlank(dto.getTitle()))
            return QCUnifyReturnValue.Warn("主题/标题不能为空");
        if (StringUtils.isBlank(dto.getContent()))
            return QCUnifyReturnValue.Warn("内容描述不能为空");
        if (StringUtils.isBlank(dto.getEdutype()))
            return QCUnifyReturnValue.Warn("类型不能为空");
        if (StringUtils.isBlank(dto.getEdumode()))
            return QCUnifyReturnValue.Warn("开展形式不能为空");
        if (dto.getHour() == null)
            return QCUnifyReturnValue.Warn("时长不能为空");
        if (dto.getPersoncount() == null)
            return QCUnifyReturnValue.Warn("参加人数不能为空");
        if (dto.getDoccount() == null)
            return QCUnifyReturnValue.Warn("发放资料数量不能为空");

        EhsEduRecord en = EhsEduRecordMapper.MAPPER.toEntity(dto);
        en.setId(IdentifierUtil.randomUUID());

        if (repository.insert(en) < 0x1) {
            return QCUnifyReturnValue.Warn("保存失败");
        }
        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改记录
     *
     * @param dto
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/10/29
     */
    public String update(EduRecordDto dto) {
        if (dto == null)
            return QCUnifyReturnValue.Warn("新增对象不能为空");
        if (StringUtils.isBlank(dto.getId()))
            return QCUnifyReturnValue.Warn("记录ID不能为空");
        if (StringUtils.isBlank(dto.getOrgcode()))
            return QCUnifyReturnValue.Warn("组织代码不能为空");
        if (StringUtils.isBlank(dto.getBegintm()))
            return QCUnifyReturnValue.Warn("开始时间不能为空");
        if (StringUtils.isBlank(dto.getEndtm()))
            return QCUnifyReturnValue.Warn("结束时间不能为空");
        if (StringUtils.isBlank(dto.getTitle()))
            return QCUnifyReturnValue.Warn("主题/标题不能为空");
        if (StringUtils.isBlank(dto.getContent()))
            return QCUnifyReturnValue.Warn("内容描述不能为空");
        if (StringUtils.isBlank(dto.getEdutype()))
            return QCUnifyReturnValue.Warn("类型不能为空");
        if (StringUtils.isBlank(dto.getEdumode()))
            return QCUnifyReturnValue.Warn("开展形式不能为空");
        if (dto.getHour() == null)
            return QCUnifyReturnValue.Warn("时长不能为空");
        if (dto.getPersoncount() == null)
            return QCUnifyReturnValue.Warn("参加人数不能为空");
        if (dto.getDoccount() == null)
            return QCUnifyReturnValue.Warn("发放资料数量不能为空");
        if (Objects.isNull(repository.selectById(dto.getId())))
            return QCUnifyReturnValue.Warn("修改的记录不存在");

        EhsEduRecord en = EhsEduRecordMapper.MAPPER.toEntity(dto);
        repository.updateById(en);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除记录
     *
     * @param id 培训记录ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/10/29
     */
    public String delete(String id) {
        repository.deleteById(id);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取记录人员关联信息
     *
     * @param eduRecordId  培训记录ID
     * @param projectUsers 当前项目用户
     * @return List<EduRecordUsersDto>
     * @author QuCheng Tech
     * @since 2024/10/29
     */
    public List<EduRecordUsersDto> getUsers(String eduRecordId, List<UserSimpleInfoDto> projectUsers) throws QCPromptException {
        if (StringUtils.isBlank(eduRecordId))
            throw new QCPromptException("培训记录ID不能为空");
        if (CollectionUtils.isEmpty(projectUsers))
            throw new QCPromptException("当前项目中无有效用户");

        List<EduRecordUsersDto> result = new ArrayList<>();

        //查询指定培训记录ID的人员ID
        LambdaQueryWrapper<EhsEduUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(EhsEduUser::getEduid, eduRecordId);
        List<EhsEduUser> eduUsers = userRepository.selectList(userWrapper);
        List<Integer> eduUids = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(eduUsers)) {
            eduUids = eduUsers.stream().map(EhsEduUser::getUserid).collect(Collectors.toList());
        }

        for (UserSimpleInfoDto info : projectUsers) {
            Integer uid = Integer.parseInt(String.valueOf(info.getId()));
            EduRecordUsersDto dto = new EduRecordUsersDto();
            dto.setId(uid);
            dto.setName(info.getName());
            dto.setPhone(info.getPhone());
            if (CollectionUtils.isNotEmpty(eduUids)) {
                boolean checked = eduUids.stream().filter(u -> u == uid).findAny().isPresent();
                dto.setChecked(checked);
            }
            result.add(dto);
        }

        return result;
    }

    /**
     * 设置记录人员关联
     *
     * @param dto
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/10/29
     */
    public String setUsers(EduRecordSetUsersDto dto) {
        if (dto == null)
            return QCUnifyReturnValue.Warn("设置信息不能为空");
        if (StringUtils.isBlank(dto.getEduid()))
            return QCUnifyReturnValue.Warn("培训记录ID不能为空");
        if (Objects.isNull(repository.selectById(dto.getEduid())))
            return QCUnifyReturnValue.Warn("培训记录不存在");

        //清除指定培训记录人员
        LambdaQueryWrapper<EhsEduUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsEduUser::getEduid, dto.getEduid());
        userRepository.delete(wrapper);

        //新增指定培训记录人员
        if (CollectionUtils.isNotEmpty(dto.getUids())) {
            for (int userId : dto.getUids()) {
                EhsEduUser en = new EhsEduUser();
                en.setEduid(dto.getEduid());
                en.setUserid(userId);
                userRepository.insert(en);
            }
        }

        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取指定组织机构下的时间段内的所有培训集合
     *
     * @param orgCode   组织机构代码
     * @param beginTime 查询开始时间
     * @param endTime   查询结束时间
     * @author QuCheng Tech
     */
    public List<EhsEduRecord> getAllEduRecord(String orgCode, Date beginTime, Date endTime) throws QCPromptException {
        if (StringUtils.isBlank(orgCode)) throw new QCPromptException("组织机构代码不能为空");

        LambdaQueryWrapper<EhsEduRecord> wrapper = new LambdaQueryWrapper<>();
        //组织机构代码，必须有，判断相等
        wrapper.eq(EhsEduRecord::getOrgcode, orgCode);
        /*安全培训的时间条件判断需要考虑以下几种不同情况：
            1.查询的起止时间前后都包含培训起始时间，查询时间段包含整个计划时间段；
            pbtm>=tm1 and petm<=tm2
            2.查询的起止时间前后都被计划时间包含，查询的时间段是计划时间段中间的部分时间；
            pbtm<=tm1 and petm>=tm2
            3.查询的起始时间被计划时间包含，查询时间段包含计划时间中的前部分时间；
            查询的截止时间被计划时间包含，查询时间段包含计划时间中的后部分时间；
            pbtm<=tm2 and petm>=tm1
        */
        wrapper.and(q -> {
            (q.ge(EhsEduRecord::getBegintm, beginTime).le(EhsEduRecord::getEndtm, endTime)).or()
                    .le(EhsEduRecord::getBegintm, beginTime).ge(EhsEduRecord::getEndtm, endTime).or()
                    .le(EhsEduRecord::getBegintm, endTime).ge(EhsEduRecord::getEndtm, beginTime);
        });

        return repository.selectList(wrapper);
    }
}
